/******************************************************************************
//������������STM32F103C8
//              GND   ��Դ��
//              VCC   ��5V��3.3v��Դ
//              SCL   ��PA5��SCL��
//              SDA   ��PA7��SDA��
//              RES   ��PB0
//              DC    ��PB1
//              CS    ��PA4 
//				BL		��PB10
*******************************************************************************/
#include "LCD/Lcd_Driver.h"
#include "delay.h"

//Һ��IO��ʼ������
void LCD_GPIO_Init(void)
{

//	GPIO_InitTypeDef  GPIO_InitStructure;
//	      
//	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB ,ENABLE);
//	
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_10| GPIO_Pin_1;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//	GPIO_Init(GPIOB, &GPIO_InitStructure);
//      
//	
//		RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE);
//	
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_7;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**
 * @brief 通过SPI总线写入一个8位数据
 * @param Data 要写入的8位数据 
 */
void SPI_WriteData(uint8_t Data)
{
    unsigned char i = 0;
    for (i = 8; i > 0; i--)  // 循环8次，逐位发送 
    {
        if (Data & 0x80)      // 检查最高位（MSB）
            LCD_SDA_SET;       // 如果为1，SDA置高
        else 
            LCD_SDA_CLR;       // 如果为0，SDA置低
 
        LCD_SCL_CLR;          // 时钟拉低（准备发送数据）
        LCD_SCL_SET;          // 时钟拉高（数据锁存）
        Data <<= 1;           // 左移一位，准备发送下一位 
    }
}

/**
 * @brief 向LCD写入一个8位命令 
 * @param Index 命令字节 
 */
void Lcd_WriteIndex(uint8_t Index)
{
    LCD_CS_CLR;       // 片选拉低（选中LCD）
    LCD_RS_CLR;       // RS置低（表示写入命令）
    SPI_WriteData(Index);  // 发送命令 
    LCD_CS_SET;       // 片选拉高（取消选中）
}

/**
 * @brief 向LCD写入一个8位数据
 * @param Data 数据字节 
 */
void Lcd_WriteData(uint8_t Data)
{
    LCD_CS_CLR;       // 片选拉低（选中LCD）
    LCD_RS_SET;       // RS置高（表示写入数据）
    SPI_WriteData(Data);  // 发送数据 
    LCD_CS_SET;       // 片选拉高（取消选中）
}

/**
 * @brief 向LCD写入一个16位数据（用于RGB565颜色数据）
 * @param Data 16位数据（高8位先发送）
 */
void LCD_WriteData_16Bit(uint16_t Data)
{
    LCD_CS_CLR;       // 片选拉低（选中LCD）
    LCD_RS_SET;       // RS置高（表示写入数据）
    SPI_WriteData(Data >> 8);  // 先发送高8位 
    SPI_WriteData(Data);       // 再发送低8位
    LCD_CS_SET;       // 片选拉高（取消选中）
}

/**
 * @brief 向LCD写入一个寄存器配置（命令+数据）
 * @param Index 命令字节 
 * @param Data 数据字节 
 */
void Lcd_WriteReg(uint8_t Index, uint8_t Data)
{
    Lcd_WriteIndex(Index);  // 写入命令
    Lcd_WriteData(Data);    // 写入数据
}

/**
 * @brief 复位LCD（拉低RST引脚并延时）
 */
void Lcd_Reset(void)
{
    LCD_RST_CLR;      // 复位拉低
    delay_ms(100);    // 保持100ms 
    LCD_RST_SET;      // 复位拉高
    delay_ms(50);     // 等待50ms稳定
}

/**
 * @brief 初始化1.44英寸LCD（ST7735R驱动）
 */
void Lcd_Init(void)
{	
    LCD_GPIO_Init();  // 初始化GPIO（未展示具体实现）
    Lcd_Reset();      // 硬件复位LCD 
 
    // ST7735R初始化序列
    Lcd_WriteIndex(0x11);  // 退出睡眠模式
    delay_ms(120);         // 等待120ms
 
    // 设置帧率控制 
    Lcd_WriteIndex(0xB1);  
    Lcd_WriteData(0x01);  
    Lcd_WriteData(0x2C);  
    Lcd_WriteData(0x2D);  

	Lcd_WriteIndex(0xB2); 
	Lcd_WriteData(0x01); 
	Lcd_WriteData(0x2C); 
	Lcd_WriteData(0x2D); 

	Lcd_WriteIndex(0xB3); 
	Lcd_WriteData(0x01); 
	Lcd_WriteData(0x2C); 
	Lcd_WriteData(0x2D); 
	Lcd_WriteData(0x01); 
	Lcd_WriteData(0x2C); 
	Lcd_WriteData(0x2D); 
	
	Lcd_WriteIndex(0xB4); //Column inversion 
	Lcd_WriteData(0x07); 
	
	//ST7735R Power Sequence
	Lcd_WriteIndex(0xC0); 
	Lcd_WriteData(0xA2); 
	Lcd_WriteData(0x02); 
	Lcd_WriteData(0x84); 
	Lcd_WriteIndex(0xC1); 
	Lcd_WriteData(0xC5); 

	Lcd_WriteIndex(0xC2); 
	Lcd_WriteData(0x0A); 
	Lcd_WriteData(0x00); 

	Lcd_WriteIndex(0xC3); 
	Lcd_WriteData(0x8A); 
	Lcd_WriteData(0x2A); 
	Lcd_WriteIndex(0xC4); 
	Lcd_WriteData(0x8A); 
	Lcd_WriteData(0xEE); 
	
	Lcd_WriteIndex(0xC5); //VCOM 
	Lcd_WriteData(0x0E); 
	
	Lcd_WriteIndex(0x36); //MX, MY, RGB mode 
	Lcd_WriteData(0xC0); 
	
	//ST7735R Gamma Sequence
	Lcd_WriteIndex(0xe0); 
	Lcd_WriteData(0x0f); 
	Lcd_WriteData(0x1a); 
	Lcd_WriteData(0x0f); 
	Lcd_WriteData(0x18); 
	Lcd_WriteData(0x2f); 
	Lcd_WriteData(0x28); 
	Lcd_WriteData(0x20); 
	Lcd_WriteData(0x22); 
	Lcd_WriteData(0x1f); 
	Lcd_WriteData(0x1b); 
	Lcd_WriteData(0x23); 
	Lcd_WriteData(0x37); 
	Lcd_WriteData(0x00); 	
	Lcd_WriteData(0x07); 
	Lcd_WriteData(0x02); 
	Lcd_WriteData(0x10); 

	Lcd_WriteIndex(0xe1); 
	Lcd_WriteData(0x0f); 
	Lcd_WriteData(0x1b); 
	Lcd_WriteData(0x0f); 
	Lcd_WriteData(0x17); 
	Lcd_WriteData(0x33); 
	Lcd_WriteData(0x2c); 
	Lcd_WriteData(0x29); 
	Lcd_WriteData(0x2e); 
	Lcd_WriteData(0x30); 
	Lcd_WriteData(0x30); 
	Lcd_WriteData(0x39); 
	Lcd_WriteData(0x3f); 
	Lcd_WriteData(0x00); 
	Lcd_WriteData(0x07); 
	Lcd_WriteData(0x03); 
	Lcd_WriteData(0x10);  
	
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x7f);

	Lcd_WriteIndex(0x2b);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x9f);
	
	Lcd_WriteIndex(0xF0); //Enable test command  
	Lcd_WriteData(0x01); 
	Lcd_WriteIndex(0xF6); //Disable ram power save mode 
	Lcd_WriteData(0x00); 
	
	Lcd_WriteIndex(0x3A); //65k mode 
	Lcd_WriteData(0x05); 
	
	
	Lcd_WriteIndex(0x29);// 开启显示 	 
}


/**
 * @brief 设置LCD显示区域（用于后续数据写入）
 * @param x_start, y_start 起始坐标
 * @param x_end, y_end 结束坐标
 */
void Lcd_SetRegion(uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end)
{
    // 设置X地址范围
    Lcd_WriteIndex(0x2A);
    Lcd_WriteData(0x00);
    Lcd_WriteData(x_start);
    Lcd_WriteData(0x00);
    Lcd_WriteData(x_end + 2);  // 调整边界（部分LCD需偏移）
 
    // 设置Y地址范围 
    Lcd_WriteIndex(0x2B);
    Lcd_WriteData(0x00);
    Lcd_WriteData(y_start);
    Lcd_WriteData(0x00);
    Lcd_WriteData(y_end + 1);  // 调整边界 
 
    Lcd_WriteIndex(0x2C);      // 进入数据写入模式
}

/**
 * @brief 设置LCD光标位置（单点）
 * @param x, y 坐标
 */
void Lcd_SetXY(uint16_t x, uint16_t y)
{
    Lcd_SetRegion(x, y, x, y);  // 区域设为单点 
}
	
/**
 * @brief 在指定位置绘制一个像素点
 * @param x, y 坐标 
 * @param Data RGB565颜色值 
 */
void Gui_DrawPoint(uint16_t x, uint16_t y, uint16_t Data)
{
    Lcd_SetRegion(x, y, x + 1, y + 1);  // 设置小区域（兼容部分LCD）
    LCD_WriteData_16Bit(Data);          // 写入颜色数据 
}

// /*****************************************
//  �������ܣ���TFTĳһ�����ɫ                          
//  ���ڲ�����color  ����ɫֵ                                 
// ******************************************/
// unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y)
// {
//   unsigned int Data;
//   Lcd_SetXY(x,y);

//   //Lcd_ReadData();//���������ֽ�
//   //Data=Lcd_ReadData();
//   Lcd_WriteData(Data);
//   return Data;
// }

/**
 * @brief 清屏并填充指定颜色
 * @param Color RGB565颜色值 
 */
void Lcd_Clear(uint16_t Color)
{
    unsigned int i, m;
    Lcd_SetRegion(0, 0, X_MAX_PIXEL - 1, Y_MAX_PIXEL - 1);  // 全屏区域 
    Lcd_WriteIndex(0x2C);                                   // 进入数据写入模式 
    for (i = 0; i < X_MAX_PIXEL; i++)
        for (m = 0; m < Y_MAX_PIXEL; m++)
            LCD_WriteData_16Bit(Color);  // 逐像素填充颜色
}
